-
Notifications
You must be signed in to change notification settings - Fork 821
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Session GridField state manager #11288
base: 5
Are you sure you want to change the base?
Session GridField state manager #11288
Conversation
GridField states in session.
current gridfield state manager configuration.
…methods will be incorporated into GridFieldStateManagerInterface in the future.
I haven't done a full review yet but nothing in the code stands out as obviously bad. I'll aim to do a proper review in the next couple of days. In the meantime, there's some PHP unit test failures which look relevant.
What linting issues do you mean? The CI PHP linting job is happy with it. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Had a quick look and it broadly looks good. I haven't checked every scenario yet. I did find a couple of things:
Existing class with similar funcitonality?
There is already a SilverStripe\Forms\GridField\FormAction\SessionStore
class which seems to be storing and fetching some state related to GridField in the session - have you looked at that class at all to see how it relates to this new feature?
Child gridfield state is too sticky
In a scenario where you have a parent DataObject
model (I'll call this Parent
) in a ModelAdmin
, and that has a many_many
relation to another model (I'll call it Child
):
- Filter or sort the
Parent
gridfield inside theModelAdmin
- Click into one of the
Parent
records - Filter or sort the
Child
gridfield - Go back to the
Parent
gridfield insideModelAdmin
(either click back in the browser or use the breadcrumbs) - Click on the same
Parent
record again and view theChild
gridfield
With the session-based state, the child gridfield is still filtered/sorted when I view it again.
With the existing URL-based state, the child gridfield is reset to its default state. It's debatable, but to me this is the desirable behaviour. It would confuse me if the child gridfield is always filtered whenever I am clicking through the parent record to get to it.
$actions->push(HiddenField::create($manager->getStateKey($this->gridField), null, $gridState)); | ||
if (ClassInfo::hasMethod($manager, 'getStateRequestVar')) { | ||
$stateRequestVar = $manager->getStateRequestVar(); | ||
$stateValue = $this->getRequest()->requestVar($stateRequestVar); | ||
if ($stateValue) { | ||
$actions->push(HiddenField::create($stateRequestVar, '', $stateValue)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we need both of these hidden fields? Can you please give me a short rundown of what they each do?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We do not really need both no.
The old one is there for backwards compatibility with the default GridStateManager. That one contains the whole grid field state as json data.
The new one (from the getStateRequestVar
method) needs a different value, i.e. the given state key value from the request. It is needed with SessionGridFieldStateManager to retain the session state key when for example saving a record.
Retaining that Child state is needed in some cases, for example when going one level further. If you filter the |
I have looked at |
Seems the CI linter doesn't mind that syntax like the linter in my IDE does, so no problem there after all. |
Is there a clean way to reset the state for all gridfields other than the current one and its "parents" when clicking on a child row? If not, it's probably okay for CMS 5 since this is opt-in, but I wouldn't want to go ahead with #11267 with this sticky behaviour - and the whole point of this is to do #11267. |
$actions->push(HiddenField::create($manager->getStateKey($this->gridField), null, $gridState)); | ||
if (ClassInfo::hasMethod($manager, 'getStateRequestVar')) { | ||
$stateRequestVar = $manager->getStateRequestVar(); | ||
$stateValue = $this->getRequest()->requestVar($stateRequestVar); | ||
if ($stateValue) { | ||
$actions->push(HiddenField::create($stateRequestVar, '', $stateValue)); | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As per #11288 (comment)
$actions->push(HiddenField::create($manager->getStateKey($this->gridField), null, $gridState)); | |
if (ClassInfo::hasMethod($manager, 'getStateRequestVar')) { | |
$stateRequestVar = $manager->getStateRequestVar(); | |
$stateValue = $this->getRequest()->requestVar($stateRequestVar); | |
if ($stateValue) { | |
$actions->push(HiddenField::create($stateRequestVar, '', $stateValue)); | |
} | |
} | |
if (ClassInfo::hasMethod($manager, 'getStateRequestVar')) { | |
$stateRequestVar = $manager->getStateRequestVar(); | |
$stateValue = $this->getRequest()->requestVar($stateRequestVar); | |
if ($stateValue) { | |
$actions->push(HiddenField::create($stateRequestVar, '', $stateValue)); | |
} | |
} else { | |
$actions->push(HiddenField::create($manager->getStateKey($this->gridField), null, $gridState)); | |
} |
Description
Provides a new session-based GridField state manager, for storing all affected GridField states into session instead of in request variables.
Might be causing linting issues from the new required methods not being present in the current
GridFieldStateManagerInterface
interface, so manual checks have to be done for checking the state manager implementation for them.Manual testing steps
Can be tested in a standard Silverstripe 5.x installation by adding the following yaml config:
Issues
Pull request checklist